﻿Public Class Device
    Private m_AddrA As Integer
    Private m_AddrB As Integer
    Private m_Name As String
    Private PortIO As I_HardwareDataExchange
    Private Decoder As New Decoder
    Private m_Connected As Boolean = False
    Private Builder As New DataBuilder
    Public Property BinaryDataExchange() As I_HardwareDataExchange
        Get
            Return PortIO
        End Get
        Set(ByVal value As I_HardwareDataExchange)
            PortIO = value
        End Set
    End Property
    Public ReadOnly Property DeviceName() As String
        Get
            Return m_Name
        End Get
    End Property
    Public ReadOnly Property Connected() As Boolean
        Get
            Return m_Connected
        End Get
    End Property
    Public Property AddrA() As Integer
        Get
            Return m_AddrA
        End Get
        Set(ByVal value As Integer)
            m_AddrA = value
        End Set
    End Property
    Public Property AddrB() As Integer
        Get
            Return m_AddrB
        End Get
        Set(ByVal value As Integer)
            m_AddrB = value
        End Set
    End Property
    Public Function FocusDevice()
        If m_AddrA + m_AddrB <= 0 Then Return False
        PortIO.OpenPort()
        Dim sc As Long = My.Computer.Clock.TickCount
        Do
            If My.Computer.Clock.TickCount > sc + 5000 Then
                MsgBox("Focus Error")
                Return False
            End If
            Windows.Forms.Application.DoEvents()
        Loop Until PortIO.IsOpen
        If PortIO.IsOpen = True Then
            PortIO.ClearBuffers()
            Dim B(2) As Byte
            B(0) = CByte(m_AddrA)
            B(1) = CByte(m_AddrB)
            B(2) = 1
            PortIO.Write(B)
            Dim S As Long = My.Computer.Clock.TickCount
            Do
                'If PortIO.BytesToRead >= 5 Then Exit Do
            Loop Until My.Computer.Clock.TickCount >= S + 500

            If PortIO.BytesToRead > 0 Then
                Dim D As Byte()
                D = PortIO.Read
                Decoder.Decode(D)
                If Decoder.DataToString = "OK" Then
                    m_Connected = True
                    Return True
                End If
            End If
            PortIO.ClosePort()
            Return False
        End If
        Return False
    End Function
    Public Function GetName() As Boolean
        If MyBase.DesignMode = False Then
            PortIO.OpenPort()
            Dim sc As Long = My.Computer.Clock.TickCount
            Do
                If My.Computer.Clock.TickCount > sc + 5000 Then
                    MsgBox("Get Name Error")
                    Exit Function
                End If
                Windows.Forms.Application.DoEvents()
            Loop Until PortIO.IsOpen
            If PortIO.IsOpen = True Then
                Dim BBuff As New ByteBuffer
                Dim BC As Integer = 0
                If m_AddrA + m_AddrB <= 0 Then Return False
                PortIO.ClearBuffers()
                Dim B(2) As Byte
                B(0) = CByte(m_AddrA)
                B(1) = CByte(m_AddrB)
                B(2) = 0
                PortIO.Write(B)
                Dim S As Long = My.Computer.Clock.TickCount
                Debug.Print("Write Command")
                Do
                    If PortIO.BytesToRead >= 3 Then Exit Do
                Loop Until My.Computer.Clock.TickCount >= S + 5000
                Debug.Print("Buffer Filled:" & PortIO.BytesToRead)
                If PortIO.BytesToRead > 0 Then
                    Dim D(2) As Byte
                    D = PortIO.Read(3)
                    BBuff.Add(D)
                    Debug.Print(ByteToString(D))
                    BC = D(2)
                End If
                Do
                    If PortIO.BytesToRead >= BC Then Exit Do
                Loop Until My.Computer.Clock.TickCount >= S + 500
                Debug.Print("Buffer Filled:" & PortIO.BytesToRead)
                If PortIO.BytesToRead > 0 Then
                    Dim D As Byte()
                    D = PortIO.Read
                    BBuff.Add(D)
                    Debug.Print("Data Length : " & BBuff.Length)
                    Decoder.Decode(BBuff.ToArray)
                    m_Name = Decoder.DataToString
                    Debug.Print("Name=" & m_Name)
                    m_Connected = True
                    PortIO.ClosePort()
                    Return True
                End If
                PortIO.ClosePort()
                Return False
            End If
            Return False
        End If
        Return False
    End Function
    Private Function ByteToString(ByVal Bytes() As Byte) As String
        Dim S As String = "Byte Array = {"
        For Each B As Byte In Bytes
            S = S & B.ToString & ","
        Next
        S = S.Substring(0, S.Length - 1)
        S = S & "}"
        Return S
    End Function
    Public Function Write(ByVal Data() As Byte) As Boolean
        If PortIO.IsOpen = True Then
            PortIO.ClearBuffers()
            Dim B(2 + Data.Length) As Byte
            B(0) = CByte(m_AddrA)
            B(1) = CByte(m_AddrB)
            B(2) = Data.Length
            Array.Copy(Data, 0, B, 3, Data.Length)
            PortIO.Write(B)
            Dim S As Long = My.Computer.Clock.TickCount
            Do
                'If PortIO.BytesToRead >= 5 Then Exit Do
            Loop Until My.Computer.Clock.TickCount >= S + 500

            If PortIO.BytesToRead > 0 Then
                Dim D As Byte()
                D = PortIO.Read
                Decoder.Decode(D)
                If Decoder.DataToString = "OK" Then
                    m_Connected = True
                    Return True
                End If
            End If
            PortIO.ClosePort()
            Return False
        End If
        Return False
    End Function
    Public Function Read(ByVal Data() As Byte) As Byte()
        If PortIO.IsOpen = False Then PortIO.OpenPort()

        Dim sc As Long = My.Computer.Clock.TickCount
        Do
            If My.Computer.Clock.TickCount > sc + 5000 Then
                MsgBox("Get Name Error")
                Return Nothing
            End If
            Windows.Forms.Application.DoEvents()
        Loop Until PortIO.IsOpen
        If PortIO.IsOpen = True Then
            Dim BBuff As New ByteBuffer
            Dim BC As Integer = 0
            If m_AddrA + m_AddrB <= 0 Then Return Nothing
            PortIO.ClearBuffers()
            Dim B(2 + Data.Length) As Byte
            B(0) = CByte(m_AddrA)
            B(1) = CByte(m_AddrB)
            B(2) = Data.Length
            Array.Copy(Data, 0, B, 3, Data.Length)
            PortIO.Write(B)
            Dim S As Long = My.Computer.Clock.TickCount
            Do
                If PortIO.BytesToRead >= 3 Then Exit Do
            Loop Until My.Computer.Clock.TickCount >= S + 5000
            If PortIO.BytesToRead > 0 Then
                Dim D(2) As Byte
                D = PortIO.Read(3)
                BBuff.Add(D)
                Debug.Print(ByteToString(D))
                BC = D(2)
            End If
            Do
                If PortIO.BytesToRead >= BC Then Exit Do
            Loop Until My.Computer.Clock.TickCount >= S + 500
            If PortIO.BytesToRead > 0 Then
                Dim D As Byte()
                D = PortIO.Read
                BBuff.Add(D)
                PortIO.ClosePort()
                Return BBuff.ToArray
            End If
            PortIO.ClosePort()
            Return Nothing
        End If
        Return Nothing
    End Function
    Public Function ReadText(ByVal Data() As Byte) As String
        Decoder.Decode(Read(Data))
        Return Decoder.DataToString
    End Function
End Class
